/**
 * @author Tobias Boehm
 *
 * 01.06.2011
 */
package org.anddev.andengine.extension.tbsengine.match;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.anddev.andengine.extension.tbsengine.match.gamestate.AbsGlobalGameState;
import org.anddev.andengine.extension.tbsengine.match.gamestate.AbsPlayerGameState;
import org.anddev.andengine.extension.tbsengine.message.client.ClientChatmessageMessage;

/**
 * Instances of this class represent a turn of a {@link AbsPlayerGameState}
 * which belong to a specific {@link Round}. It contains all of its
 * {@link AbsStep}s and all {@link ClientChatmessageMessage} in chronological 
 * order which were sent during this turn.
 * <p>
 * Notice:<br>
 * This class is still being worked on. It may still change.
 * 
 * @author Tobias Boehm
 *
 */
public class Turn {

	/**
	 * A list of all {@link ClientChatmessageMessage} in chronological order
	 * which where sent during this turn.
	 */
	private final List<ClientChatmessageMessage> mInGameChatMessages = Collections.synchronizedList(new ArrayList<ClientChatmessageMessage>());
	
	/**
	 * A list of all completed steps during this turn.
	 */
	private final ArrayList<AbsStep> mCompletedSteps = new ArrayList<AbsStep>();
	
	/**
	 * A reference to the {@link AbsPlayerGameState} which plays this turn.
	 */
	private final AbsPlayerGameState mPlayerGameState;
	
	/**
	 * A reference to the overall {@link AbsGlobalGameState} of which this turn
	 * belongs to.
	 */
	private final AbsGlobalGameState mGlobalGameState;
	
	/**
	 * The ID of this turn which determines its position inside its {@link Round}.
	 */
	private final int mTurnID;
	
	/**
	 * A flag which indicates if the turn is still open.
	 */
	private boolean mTurnOpen;
	
	/**
	 * The basic constructor for a new turn.
	 * 
	 * @param pTurnID - The ID of this turn which determines its position inside its {@link Round}.
	 * @param pPlayerGameState - A reference to the {@link AbsPlayerGameState} which plays this turn.
	 * @param pGlobalGameState - A reference to the overall {@link AbsGlobalGameState} of which this turn belongs to.
	 */
	public Turn(final int pTurnID, final AbsPlayerGameState pPlayerGameState, final AbsGlobalGameState pGlobalGameState){
		
		this.mPlayerGameState = pPlayerGameState;
		
		this.mTurnID = pTurnID;
		
		this.mGlobalGameState = pGlobalGameState;
	}

	/**
	 * This method starts the turn and notifies the {@link AbsGlobalGameState}
	 * about its start.
	 */
	public void startTurn(){
		
		if(this.mTurnOpen){
			
			throw new IllegalStateException("The turn is already running");
		}
		
		this.mTurnOpen = true;
		
		this.mGlobalGameState.onTurnStarted(this);
	}
	
	/**
	 * This method closes the turn and notifies the {@link AbsGlobalGameState}
	 * about its completion.
	 */
	public void completeTurn(){
		
		if(!this.mTurnOpen){
			
			throw new IllegalStateException("The turn is already closed");
		}
		
		this.mTurnOpen = false;
		
		this.mGlobalGameState.onTurnCompleted(this);
	}
	
	/**
	 * With this method you can add completed steps to the turn.
	 * @param pStep
	 */
	public void addCompletedStep(final AbsStep pStep){
		
		if(!this.mTurnOpen){
			
			throw new IllegalStateException("The turn is already closed");
		}
		
		this.mCompletedSteps.add(pStep);
	}
	
	/**
	 * @return the mInGameChatMessages
	 */
	public List<ClientChatmessageMessage> getInGameChatMessages() {
		return mInGameChatMessages;
	}

	/**
	 * @return the mSteps
	 */
	public ArrayList<AbsStep> getSteps() {
		return mCompletedSteps;
	}

	/**
	 * @return the mPlayerGameState
	 */
	public AbsPlayerGameState getPlayerGameState() {
		return mPlayerGameState;
	}

	/**
	 * @return the mTurnID
	 */
	public int getTurnID() {
		return mTurnID;
	}

	/**
	 * @return the mTurnOpen
	 */
	public boolean isTurnOpen() {
		return mTurnOpen;
	}
}
